#include "../Timestamp.h"
#include <sys/time.h>
#include <stdio.h>
#include <cinttypes>
#include <cassert>
using namespace yhaida;

static_assert(sizeof(Timestamp) == sizeof(int64_t));

Timestamp::Timestamp()
    : _microSecondsSinceEpoch(0)
{
    
}

Timestamp::Timestamp(int64_t microseconds)
    : _microSecondsSinceEpoch(microseconds)
{
}

std::string Timestamp::toString() const
{
    char buf[32] = {0};
    //微妙转化为秒
    int64_t seconds = _microSecondsSinceEpoch / kMicroSecondsPerSecond;
    int64_t microseconds = _microSecondsSinceEpoch % kMicroSecondsPerSecond;
    //这是一种跨平台的书写方式，主要是为了同时支持32位和64位操作系统。
    // PRId64表示64位整数，在32位系统中表示long long int，在64位系统中表示long int。
    // 例子：
    // #include <inttypes.h>
    // printf("%" PRId64 "\n", value);
    // 相当于：
    // 在32位机子上
    // printf("%" "ld" "\n", value);  //64bit OS
    // 在64位机子上
    // printf("%" "lld" "\n", value);  //32bit OS
    snprintf(buf, sizeof(buf) - 1, "%" PRId64 ".%06" PRId64 "", seconds, microseconds);
    return buf;
}

std::string Timestamp::toFormattedString() const
{
    char buf[64] = {0};
    time_t seconds = static_cast<time_t>(_microSecondsSinceEpoch / kMicroSecondsPerSecond);
    int microseconds = static_cast<int>(_microSecondsSinceEpoch % kMicroSecondsPerSecond);
    struct tm tm_time;
    gmtime_r(&seconds, &tm_time);

    snprintf(buf, sizeof(buf), "%4d%02d%02d %02d:%02d:%02d.%06d",
             tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday,
             tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec,
             microseconds);
    return buf;
}

Timestamp Timestamp::now()
{
    struct timeval tv;
    //struct timeval {
    //       long    tv_sec;         /* seconds */秒    
    //       long    tv_usec;        /* and microseconds */微秒
    // };
    gettimeofday(&tv, NULL);
    int64_t seconds = tv.tv_sec;
    return Timestamp(seconds * kMicroSecondsPerSecond + tv.tv_usec);
}

Timestamp Timestamp::invalid()
{
    return Timestamp();
}
